/*
 * MetadataBlock.cpp
 *
 *  Created on: Jul 7, 2009
 *      Author: elkobir
 */

#include "MetadataBlock.h"

MetadataBlock::MetadataBlock(unsigned char* data) {

	_fileSystemSizeInBlocks = Utils::GetInt(data, 0);
	_blockSizeInBytes = Utils::GetInt(data, 4);
	_rootINode = Utils::GetInt(data, 8);
	_freeBlocksCount = Utils::GetInt(data, 12);
	_lastFreeBlockOffset = Utils::GetInt(data, 16);
	_lastFreeBlockBlock = Utils::GetInt(data, 20);
	_totalINodeCount = Utils::GetInt(data, 24);
	_freeINodeCount = Utils::GetInt(data, 28);
	_lastFreeINodeOffset = Utils::GetInt(data, 32);
	_lastFreeINodeBlock = Utils::GetInt(data, 36);

}

MetadataBlock::MetadataBlock(int dataBlockSize, int numberOfInodes, unsigned long int diskSize){

	_fileSystemSizeInBlocks = diskSize / dataBlockSize; // const
	_blockSizeInBytes = dataBlockSize; // const
	_rootINode = 0;// TODO: set to root inode (i.e c:\)
	_lastFreeBlockOffset = 0; // TODO
	_lastFreeBlockBlock = 0; // TODO
	_totalINodeCount = numberOfInodes;
	_freeINodeCount = 0;//_totalINodeCount;
	_lastFreeINodeOffset = 0; // TODO
	_lastFreeINodeBlock = 0; // TODO

	_freeBlocksCount = 0;//_fileSystemSizeInBlocks - getSuperBlocksPlusINodeArrayBlocksCount();

}

MetadataBlock::~MetadataBlock() {
	// TODO Auto-generated destructor stub
}

unsigned char* MetadataBlock::toBytes(){
	unsigned char* res = Utils::InitBytes(_blockSizeInBytes);
	//TODO who ever control res control his release memory

	Utils::IntToByte(_fileSystemSizeInBlocks, res, 0);
	Utils::IntToByte(_blockSizeInBytes, res, 4);
	Utils::IntToByte(_rootINode, res, 8);
	Utils::IntToByte(_freeBlocksCount, res, 12);
	Utils::IntToByte(_lastFreeBlockOffset, res, 16);
	Utils::IntToByte(_lastFreeBlockBlock, res, 20);
	Utils::IntToByte(_totalINodeCount, res, 24);
	Utils::IntToByte(_freeINodeCount, res, 28);
	Utils::IntToByte(_lastFreeINodeOffset, res, 32);
	Utils::IntToByte(_lastFreeINodeBlock, res, 36);

	return res;
}

int MetadataBlock::getAddressInBlockCount(){
	int result = (_blockSizeInBytes / 4) - 1;
	return result;
}

int MetadataBlock::getSuperBlocksPlusINodeArrayBlocksCount(){
	int result = 0;

	double inodesize = 50;

	int inodeArrayBlockCount = ceil(inodesize * _totalINodeCount/ (double)_blockSizeInBytes);
	result = 3 + inodeArrayBlockCount;

	return result;
}

int MetadataBlock::incFreeBlocksCount(){
	_freeBlocksCount++;

	ostringstream str; str << "freeBlocksCount incremented to: " << _freeBlocksCount <<  endl;
	Log::log(str, 0, "metadata");

	return _freeBlocksCount;
}

int MetadataBlock::decFreeBlocksCount(){
	_freeBlocksCount--;

	ostringstream str; str << "freeBlocksCount decremented to: " << _freeBlocksCount <<  endl;
	Log::log(str, 0, "metadata");

	return _freeBlocksCount;
}

int MetadataBlock::incFreeInodeCount(){
	_freeINodeCount++;

	ostringstream str; str << "freeInodeCount incremented to: " << _freeINodeCount <<  endl;
	Log::log(str, 0, "metadata");

	return _freeINodeCount;
}

int MetadataBlock::decFreeInodeCount(){
	_freeINodeCount--;

	ostringstream str; str << "freeInodeCount decremented to: " << _freeINodeCount <<  endl;
	Log::log(str, 0, "metadata");

	return _freeINodeCount;
}

int MetadataBlock::getFreeInodeCount(){
	return _freeINodeCount;
}

int MetadataBlock::getFreeBlocksCount(){
	return _freeBlocksCount;
}
